/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.<br/>
 * 项目名称 : 电子商务云服务平台
 * 创建日期 : 2016年6月28日
 * 修改历史 : 
 *     1. [2016年7月14日]修改文件 by lijialun
 * 添加Javadoc注释，更新代码规范，静态工具类增加private构造函数
 */
package com.gavinwind.inspay.common.advice;

import com.gavinwind.inspay.common.dto.SessionContext;
import com.gavinwind.inspay.common.logger.PlatformLogger;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

/**
 * 【service日志拦截器】
 * @author Gavin
 * @date Fre 24, 2016
 * @version 1.0
 * 【修改描述】
 * @author Gavin
 * @date Fre 24, 2016
 */
public class LogAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {

    /** 
    * @Fields logger : 日志记录工具 
    */
    protected final PlatformLogger logger = PlatformLogger.getLogger(getClass());
    /**
     * 拦截开始时间
     */
    private long beforeRunTime;

    /**
     * 拦截结束时间
     */
    private long afterRunTime;

    /**
     * 分隔符
     */
    private static final String SEQARATOR = "&";

    /**
     * 
     * 方法执行之前被调用
     * 
     * @param cMethod
     *            拦截方法
     * @param cPramArgs
     *            方法参数
     * @param cTarget
     *            目标代理对象
     * @throws Throwable
     *             异常
     */
    public void before(Method cMethod, Object[] cPramArgs, Object cTarget) throws Throwable {
        // 记录当前时间
        beforeRunTime = System.currentTimeMillis();
        // 类名
        String tClazzName = cTarget.getClass().getName();
        // 方法名
        String tMethodName = cMethod.getName();
        logger.info("［访问service日志start］ClassName:" + tClazzName + SEQARATOR + "MethodName:" + tMethodName);
    }

    /**
     * 
     * 方法执行之后被调用
     * 
     * @param cClazz
     *            返回对象
     * @param cMethod
     *            拦截方法
     * @param cPramArgs
     *            拦截方法参数
     * @param cTarget
     *            目标代理对象
     * @throws Throwable
     *             异常
     */
    public void afterReturning(Object cClazz, Method cMethod, Object[] cPramArgs, Object cTarget) throws Throwable {
        // 记录当前时间
        afterRunTime = System.currentTimeMillis();
        // 取得该方法运行所消耗的时间
        long tDurationTimes = afterRunTime - beforeRunTime;
        // 类名
        String tClazzName = cTarget.getClass().getName();
        // 方法名
        String tMethodName = cMethod.getName();

        String tLocalIp = SessionContext.getLocalIP();

        logger.info("［访问service日志end］＝＝》RequestIp:" + tLocalIp + SEQARATOR + "ClassName:" + tClazzName + SEQARATOR + "MethodName:" + tMethodName
                + SEQARATOR + "DurationTimes:" + tDurationTimes);
    }

    /**
     * 
     * 抛出Exception之后被调用
     * @param cMethod 拦截方法
     * @param cArgs 拦截方法参数
     * @param cTarget 目标代理对象
     * @param cEx 异常类
     * @throws Throwable 异常
     */
    public void afterThrowing(Method cMethod, Object[] cArgs, Object cTarget, Exception cEx) throws Throwable {
        String tClazzName = cTarget.getClass().getName();
        String tMethodName = cMethod.getName();
        String tExceptionClazz = cEx.getClass().getName();

        StringWriter tSw = new StringWriter();
        PrintWriter tPw = new PrintWriter(tSw);
        String tExceptionMessage = tSw.toString();
        // 取得该方法运行所消耗的时间
        long tDurationTimes = afterRunTime - beforeRunTime;
        String tLocalIp = SessionContext.getLocalIP();
        logger.error("［访问service日志］＝＝》RequestIp:" + tLocalIp + SEQARATOR + "ClassName:" + tClazzName + SEQARATOR + "MethodName:" + tMethodName
                + SEQARATOR + "DurationTimes:" + tDurationTimes + SEQARATOR + "ExceptionClass:" + tExceptionClazz + SEQARATOR + "ExceptionMessage:"
                + tExceptionMessage);
    }
}
